#compdef assh
###############################################################################
# -*- mode:sh; -*-
# Time-stamp: <Thu 2017-03-16 15:37 svarrette>
#
# Zsh completion for [assh](https://github.com/moul/advanced-ssh-config)
#
# Copyright (c) 2017 Sebastien Varrette <Sebastien.Varrette@uni.lu>
###############################################################################
# Enable this completion file by adding somewhere in your zsh configuration (most
# probably ~/.zshrc):
#     fpath=(/path/to/this/dir $fpath)
#
# Test modification of this file in live in your shell:
#
#  unfunction _assh && autoload -U _assh
#

typeset -A opt_args

# Main dispatcher
_assh()
{
    local -a _assh_cmds
    _assh_cmds=(
        'info:Display system-wide information'
        'config:Manage ssh and assh configuration'
        'sockets:Manage control sockets'
        'help:Shows a list of commands or help for one command'
        'connect:Connect to host SSH socket, used by ProxyCommand'
    )
    local curcontext="$curcontext" state line ret=1
    typeset -A opt_args
    _arguments -C \
               '(- *)'{-h,--help}'[show this help message and exit]' \
               '(- *)'{--version,-v}"[Show the version and exit]" \
               '(- *)'{-q,--quiet}"Silence warnings" \
               '(- *)'{-V,--verbose}'[Enable verbose output]' \
               '(- *)'{--debug,-D}'[Enable debug mode]' \
               '(-c --config)'{-c,--config=}'[location of config file]:filename:_files' \
               ': :->command' \
               '*:: :->options' && ret=0
    case $state in
        (command)
            _describe -t commands 'assh' _assh_cmds && ret=0
            ;;
        (options)
            curcontext=${curcontext%:*}-$line[1]:
            case $line[1] in
                (config) __assh_config && ret=0;;
                (connect) _hosts && ret=0;;
                (info)  ret=0;;
                (sockets) __assh_sockets && ret=0;;
                (help)
                    # could do better here to avoid repetition
                    _describe -t commands 'assh help' _assh_cmds && ret=0
                    ;;
            esac
            ;;
    esac
    return ret
}

## Manage ssh and assh configuration
__assh_config() {
    local -a _assh_config_cmds
    _assh_config_cmds=(
        'build:Build .ssh/config'
        'json:Returns the JSON output'
        'list:List all hosts from assh config'
        'graphviz:Generate a Graphviz graph of the hosts'
        'search:Search entries by given search text'
        'help:Shows a list of commands or help for one command'
    )
    local curcontext="$curcontext" state line
    typeset -A opt_args
    _arguments -C \
               '--help[show this help message and exit]' \
               ': :->command' \
               '*:: :->options'
    case $state in
        (command)
            _describe -t commands "assh config subcommand" _assh_config_cmds
            ;;
        (options)
            case $line[1] in
                (help)
                    _describe -t commands 'assh config help' _assh_config_cmds && ret=0
                    ;;
                (build)
                    _arguments -C \
                               {-h,--help}'[show this help message and exit]' \
                               {-e,--expand}'[Expand all fields]' \
                               '--ignore-known-hosts:Ignore known-hosts file' && ret=0
                    ;;
                (json|list)
                    _arguments -C \
                               {-e,--expand}'[Expand all fields]'  && ret=0
                    ;;
                (graphviz)
                    _arguments -C \
                               '--show-isolated-hosts:Show isolated hosts' && ret=0
                    ;;

            esac
            ;;
    esac
    return ret
}

# Manage control sockets
__assh_sockets() {
    local -a _assh_config_cmds
    _assh_sockets_cmds=(
        'list:List active control sockets'
        'flush:Close control sockets'
        'master:Open a master control socket'
    )
    local curcontext="$curcontext" state line
    typeset -A opt_args
    _arguments -C \
               '--help[show this help message and exit]' \
               ': :->command' \
               '*:: :->options'
    case $state in
        (command)
            _describe -t commands "assh sockets subcommand" _assh_sockets_cmds
            ;;
        (options)
            case $line[1] in
                (help)
                    _describe -t commands 'assh sockets help' _assh_sockets_cmds && ret=0
                    ;;
                (list|flush|master)
                    _arguments -C \
                               {-h,--help}'[show this help message and exit]' && ret=0
                    ;;
            esac
            ;;
    esac
    return ret
}
